package cn.hsa.xxx.salesReport.service.Impl;

import cn.hsa.xxx.salesReport.bo.BookSalesMonitorBO;
import cn.hsa.xxx.api.dto.BookSalesMonitorDTO;
import cn.hsa.xxx.api.service.BookSalesMonitorService;
import javafx.util.Pair;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class BookSalesMonitorServiceImpl implements BookSalesMonitorService {

    @Autowired
    private BookSalesMonitorBO bookSalesMonitorBO;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    @Scheduled(cron = "0 0 0 * * ?")
    @Transactional
    public Boolean addDailyData() {
        //获取当前时间的前一天
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = calendar.getTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dayTime = sdf.format(date);
        //redis中存入的key："hourly"+"_"+sdf("yyyy-MM-dd HH")+"_"+bookUuid
        List<Pair<String , Map<Object, Object>>> hourlyPairs =  getHashes("hourly_"+dayTime+"*");
        for(Pair<String , Map<Object, Object>> hourlyPair : hourlyPairs) {
            Map<Object, Object> hourlyMap = hourlyPair.getValue();
            BookSalesMonitorDTO bookSalesMonitorDTO = new BookSalesMonitorDTO();
            bookSalesMonitorDTO.setBookSalesUuid(hourlyPair.getKey());
            bookSalesMonitorDTO.setBookUuid((String) hourlyMap.get("bookUuid"));
            bookSalesMonitorDTO.setBookTypeUuid((String) hourlyMap.get("bookTypeUuid"));
            bookSalesMonitorDTO.setDealAmount((Float) hourlyMap.get("dealAmount"));
            bookSalesMonitorDTO.setSaleCount((int) hourlyMap.get("saleCount"));
            bookSalesMonitorDTO.setCreateTime(new Date());
            bookSalesMonitorDTO.setStatisticalTime((Date) hourlyMap.get("statisticalTime"));
            bookSalesMonitorBO.add(bookSalesMonitorDTO);
        }
        return true;
    }

    @Override
    public List<Pair<String, Integer>> getSalesVolumeRank(Date beginDate, Date endDate) {
        List<BookSalesMonitorDTO> bookSalesMonitorDTOList = bookSalesMonitorBO.getByTime(beginDate, endDate);

        //将书籍按照书籍类型分类，使用TreeMap存储,从大到小排序 key：bookUuid value：销售量
        Map<String, Integer> volumeRankMap = new TreeMap<>(Collections.reverseOrder());
        //书籍分类
        for (BookSalesMonitorDTO bookSalesMonitorDTO : bookSalesMonitorDTOList) {
            String bookUuid = bookSalesMonitorDTO.getBookUuid();
            Integer saleCount = bookSalesMonitorDTO.getSaleCount();
            //判断该类型在map中是否存在，不存在就创建，存在就更新
            if(volumeRankMap.get(bookUuid) == null) {
                volumeRankMap.put(bookUuid, saleCount);
            } else {
                saleCount += volumeRankMap.get(bookUuid);
                volumeRankMap.put(bookUuid, saleCount);
            }
        }
        //根据销售量排序
        List<Map.Entry<String, Integer>> saleList = new ArrayList<>();
        saleList.addAll(volumeRankMap.entrySet());
        //降序
        Collections.sort(saleList, (o1, o2) -> o2.getValue()-o1.getValue());
        log.warn("saleList:{}", saleList);
        List<Pair<String, Integer>> result = new ArrayList<>();
        for(Map.Entry<String, Integer> entry : saleList) {
            result.add(new Pair(entry.getKey(), entry.getValue()));
        }
        return result;
    }

    @Override
    public List<Pair<String, Float>> getSalesPriceRank(Date beginDate, Date endDate) {
        List<BookSalesMonitorDTO> bookSalesMonitorDTOList = bookSalesMonitorBO.getByTime(beginDate, endDate);

        //将书籍按照书籍类型分类，使用TreeMap存储,从大到小排序 key：bookUuid value：销售金额
        Map<String, Float> volumeRankMap = new TreeMap<>(Collections.reverseOrder());
        //书籍分类
        for (BookSalesMonitorDTO bookSalesMonitorDTO : bookSalesMonitorDTOList) {
            String bookUuid = bookSalesMonitorDTO.getBookUuid();
            Float dealAmount = bookSalesMonitorDTO.getDealAmount();
            //判断该类型在map中是否存在，不存在就创建，存在就更新
            if(volumeRankMap.get(bookUuid) == null) {
                volumeRankMap.put(bookUuid, dealAmount);
            } else {
                dealAmount += volumeRankMap.get(bookUuid);
                volumeRankMap.put(bookUuid, dealAmount);
            }
        }
        //根据销售量排序
        List<Map.Entry<String, Float>> saleList = new ArrayList<>();
        saleList.addAll(volumeRankMap.entrySet());
        //降序
        Collections.sort(saleList, (o1, o2) -> {
            return (o1.getValue() < o2.getValue()) ? 1 : -1;
        });
        //重新转换为map
        List<Pair<String, Float>> result = new ArrayList<>();
        for(Map.Entry<String, Float> entry : saleList) {
            result.add(new Pair(entry.getKey(), entry.getValue()));
        }
        return result;
    }


    //模糊查询key
    private List<Pair<String , Map<Object, Object>>> getHashes(String key) {
        Set<String> keys = (key == null) ? null : stringRedisTemplate.keys(key);
        List<Pair<String , Map<Object, Object>>>  hashes = new ArrayList<>();
        if (keys == null) {
            return null;
        } else {
            for (String k : keys) {
                hashes.add(new Pair(k, redisTemplate.opsForHash().entries(k)));
            }
            return hashes;
        }
    }
}
